package cn.broadsense.biz.service.impl;

import cn.broadsense.biz.bo.TagInfoBo;
import cn.broadsense.biz.domain.TagInfo;
import cn.broadsense.biz.domain.TagRule;
import cn.broadsense.biz.domain.TagType;
import cn.broadsense.biz.dto.TagInfoTreeDto;
import cn.broadsense.biz.mapper.TagInfoMapper;
import cn.broadsense.biz.query.TagInfoQuery;
import cn.broadsense.biz.service.TagInfoService;
import cn.broadsense.biz.service.TagRuleService;
import cn.broadsense.biz.service.TagTypeService;
import cn.broadsense.biz.utils.IdGenerationUtil;
import cn.broadsense.biz.vo.TagInfoVo;
import cn.broadsense.common.exception.ServiceException;
import cn.broadsense.common.utils.TreeUtils;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * @author lijian
 * @description
 * @date 2024年09月11日 下午4:05
 */
@Service
@RequiredArgsConstructor
public class TagInfoServiceImpl extends ServiceImpl<TagInfoMapper, TagInfo> implements TagInfoService {

    private final TagTypeService typeService;

    private final TagRuleService ruleService;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void saveTagInfo(TagInfoVo tagInfoVo) {
        String code = IdGenerationUtil.tagCode();
        TagInfo tagInfo = new TagInfo();
        tagInfo.setCode(code);
        tagInfo.setName(tagInfoVo.getName());
        if (Objects.nonNull(tagInfoVo.getTagRuleId())) {
            TagType type = typeService.lambdaQuery().select(TagType::getTypeId).eq(TagType::getTypeId, tagInfoVo.getTagTypeId()).last(" limit 1").one();
            if (type == null) {
                throw new ServiceException("标签类型不存在");
            }
            tagInfo.setTagRuleId(Long.valueOf(tagInfoVo.getTagRuleId()));
        }
        if (Objects.nonNull(tagInfoVo.getTagRuleId())) {
            TagRule rule = ruleService.lambdaQuery().select(TagRule::getId).eq(TagRule::getId, tagInfoVo.getTagRuleId()).last(" limit 1").one();
            if (rule == null) {
                throw new ServiceException("规则不存在");
            }
            tagInfo.setTagTypeId(tagInfoVo.getTagTypeId());
        }
        this.save(tagInfo);
        Integer parentId = tagInfoVo.getParentId();
        String fullId;
        if (Objects.isNull(tagInfoVo.getParentId())) {
            parentId = 0;
            fullId = "0," + tagInfo.getId();
        } else {
            TagInfo byId = this.getById(parentId);
            if (Objects.isNull(byId)) {
                throw new ServiceException("父级标签不存在");
            }
            fullId = byId.getFullId() + "," + tagInfo.getId();
        }
        tagInfo.setFullId(fullId);
        tagInfo.setParentId(parentId);
        this.updateById(tagInfo);
    }

    @Override
    public Integer getChildrenList(Integer id) {
        return this.baseMapper.getChildrenList(id);
    }

    @Override
    public List<TagInfoTreeDto> getListTree(TagInfoQuery query) {
        List<TagInfoTreeDto> listTree = this.baseMapper.getListTree(query);
        if(CollectionUtil.isNotEmpty(listTree)){
            List<TagInfo> list = this.lambdaQuery().select(TagInfo::getId, TagInfo::getName).list();
            listTree.forEach(x -> {
                Optional<TagInfo> first = list.stream().filter(y -> Objects.equals(y.getId(), x.getParentId())).findFirst();
                first.ifPresent(tagInfoTreeDto -> x.setParentName(tagInfoTreeDto.getName()));
            });
            return TreeUtils.getTree(listTree, listTree.stream().map(TagInfoTreeDto::getId).map(Objects::toString).collect(Collectors.toList()));
        }
        return Collections.emptyList();
    }

    @Override
    public TagInfo getTagInfo(Integer id) {
        TagInfo tagInfo = this.baseMapper.getTagInfo(id);
        if (Objects.nonNull(tagInfo.getParentId()) && tagInfo.getParentId() != 0) {
            TagInfo one = this.lambdaQuery().select(TagInfo::getName).eq(TagInfo::getId, tagInfo.getParentId()).last(" limit 1").one();
            tagInfo.setParentName(one.getName());
        }
        return tagInfo;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void importTagInfoList(List<TagInfoBo> list) {
        if (CollectionUtil.isEmpty(list)) {
            throw new ServiceException("导入数据不能为空");
        }
        List<TagInfo> infoList = this.lambdaQuery().select(TagInfo::getId, TagInfo::getName, TagInfo::getFullId,TagInfo::getParentId).list();
        List<TagType> typeList = typeService.lambdaQuery().select(TagType::getTypeId, TagType::getTypeName).list();
        List<TagRule> ruleList = ruleService.lambdaQuery().select(TagRule::getId, TagRule::getRuleName).list();
        for (int i = 0; i < list.size(); i++) {
            TagInfoBo bo = list.get(i);
            TagInfo tagInfo = new TagInfo();
            if (StrUtil.isEmpty(bo.getName())) {
                throw new ServiceException("第" + (i + 1) + "行标签名称不能为空");
            }
            if (bo.getName().length() > 64) {
                throw new ServiceException("第" + (i + 1) + "行标签名称不能大于64个字符");
            }
            Optional<TagInfo> first1 = infoList.stream().filter(z -> z.getName().equals(bo.getName())).findFirst();
            if (first1.isPresent()) {
                throw new ServiceException("第" + (i + 1) + "行标签 " + bo.getName() + " 已存在");
            }
            tagInfo.setName(bo.getName());
            if (StrUtil.isNotEmpty(bo.getTypeName())) {
                Optional<TagType> first = typeList.stream().filter(x -> x.getTypeName().equals(bo.getTypeName())).findFirst();
                if (!first.isPresent()) {
                    throw new ServiceException("第" + (i + 1) + "行标签类型不存在");
                }
                tagInfo.setTagTypeId(first.get().getTypeId());
            }
            if (StrUtil.isNotEmpty(bo.getRuleName())) {
                Optional<TagRule> first = ruleList.stream().filter(x -> x.getRuleName().equals(bo.getRuleName())).findFirst();
                if (!first.isPresent()) {
                    throw new ServiceException("第" + (i + 1) + "行关联规则不存在");
                }
                tagInfo.setTagRuleId(first.get().getId());
            }
            tagInfo.setCode(IdGenerationUtil.tagCode());
            this.save(tagInfo);
            int parentId = 0;
            String fullId = "";
            if (StrUtil.isNotEmpty(bo.getParentName())) {
                Optional<TagInfo> first = infoList.stream().filter(x -> x.getName().equals(bo.getParentName())).findFirst();
                if (!first.isPresent()) {
                    throw new ServiceException("第" + (i + 1) + "行上级标签不存在");
                }
                parentId = first.get().getId();
                fullId += first.get().getFullId() + "," + tagInfo.getId();
            } else {
                fullId = "0," + tagInfo.getId();
            }
            tagInfo.setParentId(parentId);
            tagInfo.setFullId(fullId);
            this.updateById(tagInfo);
        }
        ;
    }


}
